package com.ciei.dpagm.service.conditionRule.standardSpecification;

import com.alibaba.fastjson.JSONObject;
import com.ciei.dpagm.common.enums.ComparatorEnum;
import com.ciei.dpagm.common.enums.FactModeEnum;
import com.ciei.dpagm.entity.Parameter;
import com.ciei.dpagm.entity.ParameterModel;
import com.ciei.dpagm.entity.ParameterModule;
import com.ciei.dpagm.service.ParameterModelService;
import com.ciei.dpagm.service.ParameterModuleService;
import com.ciei.dpagm.service.ParameterService;
import com.ciei.dpagm.service.RuleSetService;
import com.ciei.dpagm.service.conditionRule.ConditionHandleService;
import com.ciei.dpagm.service.conditionRule.factMode.FactModeFactoryService;
import com.ciei.dpagm.util.APP;
import com.ciei.dpagm.util.ApplicationContextHolder;
import com.ciei.dpagm.util.JsonUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author pp
 * @date 2023/04/09
 */
public class SelectParameterStandardSpecificationService extends AbstractStandardSpecificationService  {
    private ParameterModelService parameterModelService;

    private ParameterModuleService parameterModuleService;

    private ParameterService parameterService;

    private Integer parameterModelIdIndex = 1;
    private Integer parameterModuleIdIndex = 2;
    private Integer parameterIdIndex = 3;

    @Override
    protected JSONObject analysis(List<String> factModeList, Integer comparator, List<String> standardSpecificationList,List<String> oldStandardSpecificationList) {
        FactModeEnum twoFactModeEnum = FactModeEnum.getEnumByValue(Integer.valueOf(factModeList.get(FactModeFactoryService.twoFactModeIndex)));
        if(twoFactModeEnum == null){
            return ConditionHandleService.notMatchAnalyzeMessage(FactModeFactoryService.twoFactModeIndex,FactModeFactoryService.title);
        }
        if(standardSpecificationList.size() < 4){
            return ConditionHandleService.ArraySizeNotMatchMessage(StandardSpecificationFactoryService.title);
        }

        switch (twoFactModeEnum) {
            case ALL_KEY_NAME_SELECT_PARAMETER:
                if(ComparatorEnum.CONTAIN.getId().equals(comparator)) {
                    return JsonUtil.getSuccess("").fluentPut(APP.DATA,analysisParameterKeyList(oldStandardSpecificationList));
                }
                break;
            case KEY_VALUE_DATA_TYPE_SELECT_PARAMETER:
                if(ComparatorEnum.EQUAL.getId().equals(comparator) || ComparatorEnum.NOT_EQUAL.getId().equals(comparator)){
                    String value = standardSpecificationList.get(standardSpecificationList.size() - 1);
                    parameterService = ApplicationContextHolder.getBean(ParameterService.class);
                    Parameter parameter = parameterService.findById(value);
                    if(parameter == null){
                        return ConditionHandleService.notFoundParameterDataMessage(StandardSpecificationFactoryService.title);
                    }
                    if(parameter.getDataType() == null){
                        return ConditionHandleService.parameterDataTypeIsNullMessage(StandardSpecificationFactoryService.title);
                    }
                    return JsonUtil.getSuccess("").fluentPut(APP.DATA,parameter.getDataType().getTypeName());
                }
                break;
            default:
                break;
        }
        return ConditionHandleService.notMatchAnalyzeMessage(StandardSpecificationFactoryService.title);
    }

    /**
     * 解析参数
     * @param standardSpecificationList
     * @return
     */
    private Parameter analysisParameter(List<String> standardSpecificationList){
        parameterService = ApplicationContextHolder.getBean(ParameterService.class);
        String parameterValue = standardSpecificationList.get(standardSpecificationList.size() - 1);
        Parameter parameter = parameterService.findById(parameterValue);
        return parameter;
    }

    @Override
    protected void conversionOptionList(List<String> standardSpecificationList, List<JSONObject> sonStandardSpecificationOptionDataList) {
        parameterService = ApplicationContextHolder.getBean(ParameterService.class);
        parameterModelService = ApplicationContextHolder.getBean(ParameterModelService.class);
        parameterModuleService = ApplicationContextHolder.getBean(ParameterModuleService.class);
        List<JSONObject> parameterOptionDataList = new ArrayList<>();
        if(standardSpecificationList.get(parameterIdIndex) != null){
            List<String> valueList = standardSpecificationList.subList(parameterIdIndex, standardSpecificationList.size());
            List<Parameter> parameterList = parameterService.findListByIds(valueList);
            for(Parameter parameter : parameterList){
                JSONObject parameterOptionData = new JSONObject();
                parameterOptionData.fluentPut("value", RuleSetService.valueIndex + RuleSetService.optionValueSeparator + parameter.getParameterId())
                        .fluentPut("label",parameter.getParameterName());
                parameterOptionDataList.add(parameterOptionData);
            }
        }
        List<JSONObject> parameterModuleOptionDataList = new ArrayList<>();
        if(standardSpecificationList.get(parameterModuleIdIndex) != null){
            JSONObject parameterModuleData = new JSONObject();
            String parameterModuleId = standardSpecificationList.get(parameterModuleIdIndex);
            ParameterModule parameterModule = parameterModuleService.findById(standardSpecificationList.get(parameterModuleIdIndex));
            parameterModuleData.fluentPut("value",RuleSetService.moduleIndex + RuleSetService.optionValueSeparator + Integer.valueOf(parameterModuleId))
                    .fluentPut("label",parameterModule == null || parameterModule.getPropertyName() == null ? "---" : parameterModule.getPropertyName())
                    .fluentPut("children",parameterOptionDataList);
            parameterModuleOptionDataList.add(parameterModuleData);
        }
        if(standardSpecificationList.get(parameterModelIdIndex) != null){
            JSONObject parameterModelData = new JSONObject();
            String parameterModelId = standardSpecificationList.get(parameterModelIdIndex);
            ParameterModel parameterModel = parameterModelService.findById(standardSpecificationList.get(parameterModelIdIndex));
            parameterModelData.fluentPut("value",RuleSetService.modelIndex + RuleSetService.optionValueSeparator + Integer.valueOf(parameterModelId))
                    .fluentPut("label",parameterModel == null || parameterModel.getPropertyName() == null ? "---" : parameterModel.getPropertyName())
                    .fluentPut("children",parameterModuleOptionDataList);
            sonStandardSpecificationOptionDataList.add(parameterModelData);
        }
    }

    /**
     * 解析参数key列表
     * @param oldStandardSpecificationList
     * @return
     */
    public List<String> analysisParameterKeyList(List<String> oldStandardSpecificationList){
        String selectParameterValuePosition = oldStandardSpecificationList.get(oldStandardSpecificationList.size() - 1);
        if(selectParameterValuePosition.contains(RuleSetService.optionValueSeparator)){
            selectParameterValuePosition = selectParameterValuePosition.substring(0, selectParameterValuePosition.indexOf(RuleSetService.optionValueSeparator));
        }
        List<String> valueList = new ArrayList<>();
        for(String oldStandardSpecification : oldStandardSpecificationList){
            String valuePrefix = selectParameterValuePosition + RuleSetService.optionValueSeparator;
            if(oldStandardSpecification.startsWith(valuePrefix)){
                String standardSpecification = oldStandardSpecification.substring(oldStandardSpecification.lastIndexOf(valuePrefix) + valuePrefix.length());
                valueList.add(standardSpecification);
            }
        }
        parameterService = ApplicationContextHolder.getBean(ParameterService.class);
        List<Parameter> parameterList = parameterService.findListByIds(valueList);
        return parameterList.stream().map(Parameter::getParameterName).collect(Collectors.toList());
    }
}
